package com.ruoyi.dm.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.dm.domain.GpsTargetInfoDetailVO;
import com.ruoyi.dm.domain.GpsTargetInfoVO;
import com.ruoyi.dm.domain.GpsTargetParam;
import com.ruoyi.dm.domain.po.GpsTargetInfoPO;
import com.ruoyi.dm.domain.po.GpsTargetStructPO;
import com.ruoyi.dm.mapper.GpsTargetInfoMapper;
import com.ruoyi.dm.service.IGpsTargetInfoService;
import com.ruoyi.utils.TranferUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GpsTargetInfoImpl extends ServiceImpl<GpsTargetInfoMapper, GpsTargetInfoPO> implements IGpsTargetInfoService {

    @Autowired
    private GpsTargetInfoMapper gpsTargetInfoMapper;

    @Autowired
    private GpsTargetInfoStructService structService;

    @Override
    public IPage<GpsTargetInfoVO> query(GpsTargetParam queryParam) {
        LambdaQueryWrapper<GpsTargetInfoPO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasLength(queryParam.getName()),GpsTargetInfoPO::getName,queryParam.getName());
        queryWrapper.like(StringUtils.hasLength(queryParam.getCode()),GpsTargetInfoPO::getCode,queryParam.getCode());
        queryWrapper.orderByDesc(GpsTargetInfoPO::getCreateDate);
        IPage page = page(queryParam.page(), queryWrapper);
        List<GpsTargetInfoVO> objects = new ArrayList<>();
        for (Object airCollectRecordPO : page.getRecords()) {
            GpsTargetInfoPO po = (GpsTargetInfoPO) airCollectRecordPO;
            GpsTargetInfoVO vo = TranferUtils.tranferGpsTargetInfoPO(po);
            objects.add(vo);
        }
        page.setRecords(objects);
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String input(MultipartFile[] files) {
        String resMag ="";
        for (MultipartFile multipartFile : files) {
            try {
                InputStream inputStream = multipartFile.getInputStream();
                Workbook workbook = WorkbookFactory.create(inputStream);
                Sheet sheet = workbook.getSheetAt(0);
                int rowNum = sheet.getLastRowNum()+1;
                //从第2行开始
                List<GpsTargetInfoPO> pos = new ArrayList<>();
                List<GpsTargetStructPO> structs = new ArrayList<>();
                LocalDateTime now = LocalDateTime.now();
                String masterCode="";
                for (int i = 2; i < rowNum; i++) {

                    Row row = sheet.getRow(i);
                    Cell firstCell = row.getCell(0);
                    if (null != firstCell ) {
                        String first = checkRow(row.getCell(0));
                        if (StringUtils.hasLength(first)) {
                            //说明是 目标信息
                            GpsTargetInfoPO po = new GpsTargetInfoPO();
                            po.setCode(Double.valueOf(checkRow(row.getCell(0))).intValue()+"");
                            po.setName(checkRow(row.getCell(1)));
                            po.setQuality(checkRow(row.getCell(2)));
                            po.setMatrix(checkRow(row.getCell(3)));
                            po.setCreateDate(now);
                            pos.add(po);
                            masterCode = po.getName().trim();
                        }
                    }
                    //结构信息
                    GpsTargetStructPO structPO = new GpsTargetStructPO();
                    structPO.setMasterCode(masterCode);
                    structPO.setName(checkRow(row.getCell(4)));
                    structPO.setArea(checkRow(row.getCell(5)));
                    structPO.setPositionX(checkRow(row.getCell(6)));
                    structPO.setPositionY(checkRow(row.getCell(7)));
                    structPO.setPositionZ(checkRow(row.getCell(8)));
                    structs.add(structPO);
                }
                this.saveBatch(pos);
                structService.saveBatch(structs);
            } catch (Exception e) {
                resMag +=String.format("文件 【{}】 导入异常，请检查格式。",multipartFile.getOriginalFilename());
                log.error("导入异常", e);
            }
        }
        return resMag;
    }

    private String checkRow(Cell cell) {
        CellType cellType = cell.getCellType();
        if (cellType.equals(CellType.STRING)) {
            return cell.getStringCellValue().trim();
        }else if (cellType.equals(CellType.NUMERIC)) {
            return cell.getNumericCellValue()+"";
        }
        throw new ServiceException("格式异常");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delFile(Long id) {
        GpsTargetInfoPO byId = getById(id);
        QueryWrapper<GpsTargetStructPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("MASTER_CODE",byId.getCode());
        structService.remove(queryWrapper);
        removeById(id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delBatch(List<Long> delParam) {
        List<GpsTargetInfoPO> byId = listByIds(delParam);
        List<String> codes = byId.stream().map(GpsTargetInfoPO::getCode).collect(Collectors.toList());
        QueryWrapper<GpsTargetStructPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("MASTER_CODE",codes);
        structService.remove(queryWrapper);
        removeBatchByIds(delParam);
        return true;
    }

    @Override
    public String export() throws Exception {
        List<GpsTargetInfoPO> pos =  gpsTargetInfoMapper.listDetail();
        ExcelUtil<GpsTargetInfoPO> excelUtil = new ExcelUtil(GpsTargetInfoPO.class);
        AjaxResult result = excelUtil.exportExcel(pos, "GPS目标站点");
        String filename =(String) result.get("data");
        String oldPath = excelUtil.getAbsoluteFile(filename);
        //表头是重复的，故合并一下
        Workbook workbook = WorkbookFactory.create(new File(oldPath));
        Sheet sheetAt = workbook.getSheetAt(0);
        CellRangeAddress cellAddresses1 = new CellRangeAddress(0,1, 0, 0);
        CellRangeAddress cellAddresses2 = new CellRangeAddress(0,1, 1, 1);
        CellRangeAddress cellAddresses3 = new CellRangeAddress(0,1, 2, 2);
        CellRangeAddress cellAddresses4 = new CellRangeAddress(0,1, 3, 3);
        sheetAt.addMergedRegion(cellAddresses1);
        sheetAt.addMergedRegion(cellAddresses2);
        sheetAt.addMergedRegion(cellAddresses3);
        sheetAt.addMergedRegion(cellAddresses4);
        String newPath = excelUtil.getAbsoluteFile("GPS目标站点-"+DateUtils.parseDateToStr("yyyyMMdd",new Date()) +".xlsx");
        workbook.write(new FileOutputStream(newPath));
        workbook.close();
        new File(oldPath).delete();
        return newPath;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean edit(GpsTargetInfoDetailVO vo)  {

        GpsTargetInfoPO po = new GpsTargetInfoPO();
        po.setName(vo.getName().trim());
        po.setCode(vo.getCode().trim());
        po.setQuality(vo.getQuality());
        po.setMatrix(vo.getMatrix());
        List<GpsTargetStructPO> structs = vo.getStructs();
        if (null != structs) {
            for (GpsTargetStructPO struct : structs) {
                struct.setId(null);
                struct.setMasterCode(po.getName().trim());
            }
        }

        if (null != vo.getId()) {
            //先清除 旧的结构信息
            GpsTargetInfoPO byId = getById(vo.getId());
            QueryWrapper<GpsTargetStructPO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("MASTER_CODE",byId.getName());
            structService.remove(queryWrapper);
            if (CollectionUtil.isNotEmpty(structs)) {
                structService.saveBatch(structs);
            }
            po.setId(vo.getId());
            updateById(po);
        }else {
            structService.saveBatch(structs);
            po.setCreateDate(LocalDateTime.now());
            save(po);
        }
        return true;
    }


    @Override
    public String modelExport() throws Exception {
        File template = new File(RuoYiConfig.getDownloadPath() + "GPS目标属性.xlsx");
        if (template.isFile()) {
            //存在模板 直接返回
        }else {
            ExcelUtil<GpsTargetInfoPO> excelUtil = new ExcelUtil<GpsTargetInfoPO>(GpsTargetInfoPO.class);
            AjaxResult result = excelUtil.exportExcel(ListUtil.empty(), "GPS目标属性");
            String filename = (String) result.get("data");
            String filePath = RuoYiConfig.getDownloadPath() + filename;

            //表头是重复的，故合并一下
            Workbook workbook = WorkbookFactory.create(new File(filePath));
            Sheet sheetAt = workbook.getSheetAt(0);
            CellRangeAddress cellAddresses1 = new CellRangeAddress(0,1, 0, 0);
            CellRangeAddress cellAddresses2 = new CellRangeAddress(0,1, 1, 1);
            CellRangeAddress cellAddresses3 = new CellRangeAddress(0,1, 2, 2);
            CellRangeAddress cellAddresses4 = new CellRangeAddress(0,1, 3, 3);
            sheetAt.addMergedRegion(cellAddresses1);
            sheetAt.addMergedRegion(cellAddresses2);
            sheetAt.addMergedRegion(cellAddresses3);
            sheetAt.addMergedRegion(cellAddresses4);
            workbook.write(new FileOutputStream(template));
            workbook.close();
            new File(filePath).delete();
        }
        return template.getAbsolutePath();
    }

    @Override
    public GpsTargetInfoDetailVO queryDetail(Long id) {
        GpsTargetInfoDetailVO detail = gpsTargetInfoMapper.detail(id);
        //将 matrix拆分
        String matrix = detail.getMatrix();
        String[] split = matrix.split(",");
        detail.setM1(split[0]);
        detail.setM2(split[1]);
        detail.setM3(split[2]);
        detail.setM4(split[3]);
        detail.setM5(split[4]);
        detail.setM6(split[5]);
        detail.setM7(split[6]);
        detail.setM8(split[7]);
        detail.setM9(split[8]);
        return detail;
    }
}
